package com.bestcem.xm.member.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.common.core.uitls.JsonUtil;
import com.bestcem.xm.member.constant.Constants;
import com.bestcem.xm.member.controller.vo.ListFootprintsVO;
import com.bestcem.xm.member.dao.FootprintDao;
import com.bestcem.xm.member.dao.MemberDao;
import com.bestcem.xm.member.entity.pojo.FootprintDO;
import com.bestcem.xm.member.entity.pojo.MemberDO;
import com.bestcem.xm.member.enums.FootprintTypeEnum;
import com.bestcem.xm.member.grpc.service.param.PageParam;
import com.bestcem.xm.member.grpc.service.param.footprint.ListFootprintRespondentSeqsParam;
import com.bestcem.xm.member.mq.message.FootprintMessage;
import com.bestcem.xm.member.service.FootprintService;
import com.bestcem.xm.member.service.MemberUserGroupService;
import com.bestcem.xm.member.service.dto.FootprintDTO;
import com.bestcem.xm.member.service.mq.send.MemberMessageSendService;
import com.bestcem.xm.member.service.param.AddFootprintParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ming.xue <ming.xue@idiaoyan.com>
 * @desc 足迹点服务
 * @date 2021-08-17
 */
@Slf4j
@Service("footprintService")
public class FootprintServiceImpl implements FootprintService {
    /**
     * JSON序列化工具
     */
    @Autowired
    private ObjectMapperTemplate objectMapperTemplate;

    /**
     * 足迹点数据访问层
     */
    @Autowired
    private FootprintDao footprintDao;

    @Autowired
    private MemberDao memberDao;
    /**
     * 消息发送模版
     */
//    @Autowired
//    private RabbitMessageSender rabbitMessageSender;
//
//    @Autowired
//    private RabbitMqConstantConfig rabbitMqConstantConfig;

    @Autowired
    private MemberUserGroupService memberUserGroupService;
    @Autowired
    private MemberMessageSendService memberMessageSendService;

    @Override
    public ServiceResult<ListFootprintsVO> listFootprints(String orgId, String memberId, PageParam pageParam,
                                                          String userId, Integer superAdmin, Integer seniorAdmin) {
        MemberDO member = memberDao.findById(memberId);
        if (member == null || !orgId.equals(member.getOrgId())) {
            if (log.isErrorEnabled()) {
                log.error("联系人不存在：{}", member);
            }
            return ServiceResult.fail("联系人不存在");
        }

        // 管理员不校验组织层级权限
        Integer adminSign = 1;
        boolean isAdmin = adminSign.equals(superAdmin) || adminSign.equals(seniorAdmin);
        if (!isAdmin && StringUtils.isNotBlank(member.getStoreId())) {
            // 组织层级权限校验
            ServiceResult<Boolean> userStoreIdsResult =
                    memberUserGroupService.checkUserGroupPermission(userId, member.getStoreId());
            if (!userStoreIdsResult.isSuccess() || Boolean.FALSE.equals(userStoreIdsResult.getData())) {
                if (log.isErrorEnabled()) {
                    log.error("查询用户组织层级失败({}):{}", userId, userStoreIdsResult);
                }
                return ServiceResult.fail("无权限访问");
            }
        }

        // 查询该公司单个联系人下足迹点总数
        Long total = footprintDao.countFootprint(orgId, memberId);

        // 分页查询足迹点
        List<FootprintDO> footprints = footprintDao.list(orgId, memberId,
                pageParam.getPage(), pageParam.getSize());
        List<FootprintDTO> rows = this.toFootprintDTOs(footprints);

        // 封装返回结果
        ListFootprintsVO listFootprintsVO = new ListFootprintsVO();
        listFootprintsVO.setRows(rows);
        listFootprintsVO.setTotal(total);
        listFootprintsVO.setPage(pageParam.getPage() + 1);
        return ServiceResult.success(listFootprintsVO);
    }

    /**
     * 获取足迹点列表
     *
     * @param orgId
     * @param memberId
     * @return
     */
    @Override
    public ServiceResult<List<FootprintDTO>> listFootprints(String orgId, String memberId) {
        List<FootprintDO> footprints = footprintDao.list(orgId, memberId);
        List<FootprintDTO> footprintDTOS = this.toFootprintDTOs(footprints);
        return ServiceResult.success(footprintDTOS);
    }

    /**
     * 新增足迹点
     *
     * @param param
     * @return
     */
    @Override
    public ServiceResult<String> addFootprint(AddFootprintParam param) {
        Integer type = param.getType();
        FootprintTypeEnum typeEnum = EnumUtil.getEnumByIndex(FootprintTypeEnum.class, param.getType());
        if (typeEnum == null) {
            return ServiceResult.fail("足迹点类型无效");
        }

        String content = objectMapperTemplate.tryConvertToJSONStr(param.getContent());
        if (StringUtils.isBlank(content)) {
            return ServiceResult.fail("足迹点内容转换为字符串失败");
        }

        String sourceKey = param.getSourceKey();
        FootprintDO footprint = footprintDao.get(type, sourceKey);
        if (footprint == null) {
            footprint = new FootprintDO();
            footprint.setCreateTime(DateUtil.getCommonDate());
            footprint.setOrgId(param.getOrgId());
            footprint.setMemberId(param.getMemberId());
            footprint.setType(type);
            footprint.setSourceKey(sourceKey);
            footprint.setUpdateTime(footprint.getCreateTime());
        } else {
            footprint.setUpdateTime(DateUtil.getCommonDate());
        }
        footprint.setContent(content);
        footprint.setFootprintTime(param.getFootprintTime());
        String id = footprintDao.saveOrUpdateFootprint(footprint);
        return ServiceResult.success(id);
    }

    /**
     * 发布足迹点
     *
     * @param param
     * @return
     */
    @Override
    public ServiceResult<String> publishFootprint(AddFootprintParam param) {
        FootprintMessage footprint = this.toFootprintMessage(param);
        try {
//            rabbitMessageSender.sendMsg(rabbitMqConstantConfig.getAppBpDirectExchange(),
//                    rabbitMqConstantConfig.getAppBpRoutingKey(), "member.footprint_save", footprint);

            memberMessageSendService.footprintSaveSend(footprint);
        } catch (Exception e) {
            log.error("发布足迹点失败", e);
            return ServiceResult.fail("发布足迹点失败");
        }
        return ServiceResult.success(Constants.SUCCESS);
    }

    @Override
    public ServiceResult<List<String>> listFootprintRespondentSeqs(ListFootprintRespondentSeqsParam param) {
        List<FootprintDO> footprints =
                footprintDao.findByOrgIdAndType(param.getOrgId(), FootprintTypeEnum.SURVEY.getIndex());
        if (CollUtil.isNotEmpty(footprints)) {
            return ServiceResult.success(
                    footprints.stream().map(FootprintDO::getSourceKey).collect(Collectors.toList()));
        }
        return ServiceResult.success();
    }

    @Override
    public List<FootprintDO> listFootprintsByIsCopy() {
        List<FootprintDO> footprints =
                footprintDao.listFootprintsByIsCopy(1, FootprintTypeEnum.SURVEY.getIndex());
        return footprints;
    }

    @Override
    public void updateContent(FootprintDO item) {
        footprintDao.updateContent(item.getId(), item.getContent());
    }

    /**
     * 类型转换
     *
     * @param param
     * @return
     */
    private FootprintMessage toFootprintMessage(AddFootprintParam param) {
        FootprintMessage message = new FootprintMessage();
        message.setOrgId(param.getOrgId());
        message.setMemberId(param.getMemberId());
        message.setType(param.getType());
        message.setSourceKey(param.getSourceKey());
        message.setContent(param.getContent());
        message.setFootprintTime(param.getFootprintTime());
        return message;
    }


    /**
     * 类型转换
     *
     * @param message
     * @return
     */
    private AddFootprintParam toAddFootprintParam(FootprintMessage message) {
        AddFootprintParam param = new AddFootprintParam();
        if (message != null) {
            param.setOrgId(message.getOrgId());
            param.setMemberId(message.getMemberId());
            param.setType(message.getType());
            param.setSourceKey(message.getSourceKey());
            param.setContent(message.getContent());
            param.setFootprintTime(message.getFootprintTime());
        }

        return param;
    }

    /**
     * 数据转换
     *
     * @param footprints
     * @return
     */
    private List<FootprintDTO> toFootprintDTOs(List<FootprintDO> footprints) {
        if (CollectionUtils.isEmpty(footprints)) {
            return Collections.emptyList();
        }

        return footprints.stream().map(this::toFootprintDTO).collect(Collectors.toList());
    }

    /**
     * 数据转换
     *
     * @param footprint
     * @return
     */
    private FootprintDTO toFootprintDTO(FootprintDO footprint) {
        FootprintDTO footprintDTO = new FootprintDTO();
        if (footprint == null) {
            return footprintDTO;
        }

        String content = footprint.getContent();
        JSONObject contentJson = JsonUtil.tryConvertToJSONObject(content);
        if (contentJson == null) {
            log.error("footprint.content convert to JSONObject failed, content: {}, footprint: {}",
                    content, footprint);
        }

        footprintDTO.setId(footprint.getId());
        footprintDTO.setOrgId(footprint.getOrgId());
        footprintDTO.setMemberId(footprint.getMemberId());
        footprintDTO.setType(footprint.getType());
        footprintDTO.setSourceKey(footprint.getSourceKey());
        footprintDTO.setFootprintTime(footprint.getFootprintTime());
        footprintDTO.setContent(contentJson);
        return footprintDTO;
    }
}
